package com.garlic.face.jlf.presenter;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.xdevicemanager.api.XDeviceManager;
import com.alipay.zoloz.smile2pay.service.ZolozCallback;
import com.garlic.face.jlf.App;
import com.garlic.face.jlf.transaction.Means;
import com.garlic.face.jlf.transaction.ServiceInterface;
import com.garlic.face.jlf.transaction.alipay.AlipayCallBack;
import com.garlic.face.jlf.transaction.alipay.AlipayClient;
import com.garlic.face.jlf.transaction.alipay.AlipayResponse;
import com.garlic.face.jlf.transaction.alipay.DefaultAlipayClient;
import com.garlic.face.jlf.transaction.alipay.request.ZolozAuthenticationCustomerSmilepayInitializeRequest;
import com.garlic.face.jlf.transaction.alipay.response.ZolozAuthenticationCustomerSmilepayInitializeResponse;
import com.garlic.face.jlf.transaction.bean.PayFlow;
import com.garlic.face.jlf.transaction.constances.JLFConstant;
import com.garlic.face.jlf.ui.PayWayActivity;
import com.garlic.face.jlf.utils.LogUtils;
import com.garlic.face.jlf.utils.ToastUtils;
import com.garlic.face.jlf.utils.Tools;
import com.garlic.face.jlf.utils.ZolozUtils;

import org.json.JSONException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import static com.garlic.face.jlf.utils.ZolozUtils.SMILEPAY_TXT_FAIL;

/**
 * @author wenhui02.liu
 * @date 2018/8/13.
 */

public class PayWayPresenter implements PayWayContract.Presenter {

    String TAG = "PayWayPresenter";
    PayWayContract.View mView;
    private ZolozUtils mZolozUtils = ZolozUtils.getInstance(App.getContext());
    private XDeviceManager mXDeviceManager = null;
    private Dialog mDialog = null;


    //刷脸支付相关
    public static final String SMILEPAY_CODE_SUCCESS = "10000";
    public static final String SMILEPAY_SUBCODE_LIMIT = "ACQ.PRODUCT_AMOUNT_LIMIT_ERROR";
    public static final String SMILEPAY_SUBCODE_BALANCE_NOT_ENOUGH = "ACQ.BUYER_BALANCE_NOT_ENOUGH";
    public static final String SMILEPAY_SUBCODE_BANKCARD_BALANCE_NOT_ENOUGH = "ACQ.BUYER_BANKCARD_BALANCE_NOT_ENOUGH";
    public static final String KEY_INIT_RESP_NAME = "zim.init.resp";
    // 值为"1000"调用成功
    // 值为"1003"用户选择退出
    // 值为"1004"超时
    // 值为"1005"用户选用其他支付方式
    public static final String CODE_SUCCESS = "1000";
    public static final String CODE_EXIT = "1003";
    public static final String CODE_TIMEOUT = "1004";
    public static final String CODE_OTHER_PAY = "1005";
    static final String TXT_EXIT = "已退出刷脸支付";
    static final String TXT_TIMEOUT = "操作超时";
    static final String TXT_OTHER_PAY = "已退出刷脸支付";
    static final String TXT_OTHER = "抱歉未支付成功，请重新支付";

    public PayWayPresenter(PayWayContract.View view) {
        mView = view;
        try {
            mXDeviceManager = new XDeviceManager(App.getContext());
            mXDeviceManager.initContext();
        } catch (Exception e) {
            if (!TextUtils.isEmpty(e.getMessage())) {
                e.printStackTrace();
                LogUtils.e("BASE ACTIVITY " + e.getMessage());
            }
        }
    }


    @Override
    public void cancelTransaction() {
        ServiceInterface.getInstance().cancelTrade("", "");
    }

    /**
     * 发起刷脸支付请求，先zolozGetMetaInfo获取本地app信息，然后调用服务端获取刷脸付协议.
     */
    @Override
    public void smilePay() {
        mZolozUtils.getZoloz(App.getContext()).zolozGetMetaInfo(mZolozUtils.getMerchantInfo(),
                new ZolozCallback() {
                    @Override
                    public void response(Map smileToPayResponse) {
                        if (smileToPayResponse == null) {
                            LogUtils.e(TAG + "response is null");
                            mView.promptText(PayWayActivity.TOAST_FAIL, TXT_OTHER);
                            return;
                        }
                        LogUtils.d("刷脸支付" + JSON.toJSONString(smileToPayResponse), true);
                        String code = (String) smileToPayResponse.get("code");
                        String metaInfo = (String) smileToPayResponse.get("metainfo");

                        //获取metainfo成功
                        if (ZolozUtils.CODE_SUCCESS.equalsIgnoreCase(code) && metaInfo != null) {
                            LogUtils.d("metanfo is:" + metaInfo, true);

                            //正式接入请上传metaInfo到服务端，不要忘记UrlEncode，使用服务端使用的sdk从服务端访问openapi获取zimId和zimInitClientData；
                            AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                                    App.getAppId(),
                                    App.getAppKey(),
                                    "json",
                                    "utf-8",
                                    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkr\n" +
                                            "IvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsra\n" +
                                            "prwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUr\n" +
                                            "CmZYI/FCEa3/cNMW0QIDAQAB",
                                    "RSA");
                            ZolozAuthenticationCustomerSmilepayInitializeRequest request
                                    = new ZolozAuthenticationCustomerSmilepayInitializeRequest();
                            JSONObject biz = new JSONObject();
                            biz.put("zimmetainfo", metaInfo);
                            request.setBizContent(biz.toJSONString());

                            //起一个异步线程发起网络请求
                            alipayClient.execute(request,
                                    new AlipayCallBack() {
                                        @Override
                                        public AlipayResponse onResponse(AlipayResponse response) {
                                            LogUtils.d("AlipayResponse:" + response, true);
                                            if (response != null && SMILEPAY_CODE_SUCCESS.equals(response.getCode())) {
                                                try {
                                                    ZolozAuthenticationCustomerSmilepayInitializeResponse zolozResponse
                                                            = (ZolozAuthenticationCustomerSmilepayInitializeResponse) response;

                                                    String result = zolozResponse.getResult();
                                                    JSONObject resultJson = JSON.parseObject(result);
                                                    String zimId = resultJson.getString("zimId");
                                                    String zimInitClientData = resultJson.getString("zimInitClientData");
                                                    //人脸调用
                                                    smile(zimId, zimInitClientData);
                                                } catch (Exception e) {
                                                    mView.promptText(PayWayActivity.TOAST_FAIL, TXT_OTHER);
                                                }
                                            } else {
                                                mView.promptText(PayWayActivity.TOAST_FAIL, TXT_OTHER);
                                            }
                                            return null;
                                        }
                                    });
                        } else {
                            String msg = (String) smileToPayResponse.get("msg");
                            if (TextUtils.isEmpty(msg)) {
                                msg = TXT_OTHER;
                            }
                            mView.promptText(PayWayActivity.TOAST_FAIL, msg);
                        }
                    }
                });
    }

    @Override
    public void destoryZoloz() {
        mZolozUtils.getZoloz(App.getContext()).zolozUninstall();
    }

    @Override
    public void parseResponse(org.json.JSONObject jsonObject) {
        try {
            String interfaceType = jsonObject.getString("INTERFACETYPE");
            String retflag = jsonObject.getString("retflag");
            String retmsg = jsonObject.getString("retmsg");
            if (interfaceType.equals(JLFConstant.TAG_CANCELTRADE_RESPONSE)) {
                mView.hideProgress();
                if (retflag.equals("0")) {
                    Tools.clearTrade();
                    mView.gotoMain();
                } else {
                    ToastUtils.toastShow(retmsg, ToastUtils.ERROR);
                    LogUtils.e(retmsg);
                }
            } else if (interfaceType.equals(JLFConstant.TAG_PAY_RESPONSE)) {
                mView.hideProgress();
                if (retflag.equals("0")) {
                    Means.getInstance().setTendCount(Means.getInstance().getTendCount() + 1);
                    PayFlow payFlow = new PayFlow();
                    payFlow.setAmount(jsonObject.getDouble("amount"));
                    payFlow.setChange(jsonObject.getDouble("change"));
                    payFlow.setFlowid(Means.getInstance().getTendCount());
                    payFlow.setKeyindex("4");
                    payFlow.setPayid(jsonObject.getString("payid"));
                    payFlow.setTrace(jsonObject.getString("trace"));
                    String receiptLines = jsonObject.getString("receiptLines");
                    if(!TextUtils.isEmpty(receiptLines)) {
                        String[] receiptArray = receiptLines.replace("[", "").replace("]", "").split(",");
                        ArrayList<String> receiptList = new ArrayList<String>();
                        for (int i = 0; i < receiptArray.length; i++) {
                            receiptList.add(receiptArray[i]);
                        }
                        Means.getInstance().setPrintBillHead(receiptList);
                    }
                    Means.getInstance().getPayHead().add(payFlow);
                    //if (jsonObject.getString("remain").equals("0.00")) {
                        //支付完成
                        mView.toSuccssActivity();
                   // } else {
                        // TODO: 2018/7/24 部分付款
                   // }
                } else {
                    ToastUtils.toastShow("付款失败：" + retmsg, ToastUtils.ERROR);
//                    mView.toFailureActivity(retmsg);
                    mView.showProgress();
                    ServiceInterface.getInstance().stateLogin();
                }
            } else if(interfaceType.equals(JLFConstant.TAG_STATE_RESPONSE)){
                if (retflag.equals("0")) {
                    mView.hideProgress();
                    if (retmsg.equals(JLFConstant.POS_PARTIAL_PAYMENT)) {
                        mView.toFailureActivity(retmsg, JLFConstant.SCO_PARTIAL_PAY_PSV);
                    }else {
                        mView.toFailureActivity(retmsg, "");
                    }
                }else {
                    mView.hideProgress();
                    //获取状态失败
//                    ToastUtils.toastShow("获取POS状态失败   需要重启POS", ToastUtils.ERROR);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void destoryMXdevice() {
        try{
            if (mXDeviceManager != null) {
                mXDeviceManager.uninitContext();
                mXDeviceManager = null;
            }
        }catch (Exception e){
            e.printStackTrace();
            LogUtils.e("BASE ACTIVITY " + e.getMessage());
        }
    }

    /**
     * 发起刷脸支付请求.
     *
     * @param zimId    刷脸付token，从服务端获取，不要mock传入
     * @param protocal 刷脸付协议，从服务端获取，不要mock传入
     */
    private void smile(String zimId, String protocal) {
        Map params = new HashMap();
        params.put(KEY_INIT_RESP_NAME, protocal);
        mZolozUtils.getZoloz(App.getContext()).zolozVerify(zimId, params, new ZolozCallback() {
            @Override
            public void response(final Map smileToPayResponse) {
                if (smileToPayResponse == null) {
                    mView.promptText(PayWayActivity.TOAST_FAIL, TXT_OTHER);
                    return;
                }

                String code = (String) smileToPayResponse.get("code");
                String fToken = (String) smileToPayResponse.get("ftoken");
                String subCode = (String) smileToPayResponse.get("subCode");
                String msg = (String) smileToPayResponse.get("msg");

                LogUtils.e("xxxx ftoken is:" + fToken + " code:" + code+" subCode:"+subCode+" msg:"+msg);

                //刷脸成功
                if (CODE_SUCCESS.equalsIgnoreCase(code) && fToken != null) {
                    LogUtils.d("xxxxx 刷脸成功，返回ftoken为:" + fToken, true);
                    //promptText("刷脸成功，返回ftoken为:" + fToken);
                    //这里在Main线程，网络等耗时请求请放在异步线程中
                    //后续这里可以发起支付请求
                    //https://docs.open.alipay.com/api_1/alipay.trade.pay
                    //需要修改两个参数
                    //scene固定为security_code
                    //auth_code为这里获取到的fToken值
                    //支付一分钱，支付需要在服务端发起，这里只是模拟
                    try {
                        Double d_amount = Means.getInstance().getRec_Tran().getAmount();
                        Double d_remain = Means.getInstance().getRec_Tran().getRemian();
                        String amount = d_amount+"";
                        String ytAmount = amount +"";
                        pay(fToken, /*"0.01"*/amount,ytAmount);
                    } catch (Exception e) {
                        e.printStackTrace();
                        mView.promptText(PayWayActivity.TOAST_FAIL, SMILEPAY_TXT_FAIL);
                    }
                } else if (CODE_EXIT.equalsIgnoreCase(code)) {
                    mView.promptText(PayWayActivity.TOAST_INFO, TXT_EXIT);
                } else if (CODE_TIMEOUT.equalsIgnoreCase(code)) {
                    mView.promptText(PayWayActivity.TOAST_INFO, TXT_TIMEOUT);
                } else if (CODE_OTHER_PAY.equalsIgnoreCase(code)) {
                    mView.promptText(PayWayActivity.TOAST_INFO, TXT_OTHER_PAY);
                } else {
                    String txt = TXT_OTHER;
                    if (!TextUtils.isEmpty(subCode)) {
                        txt = txt + "(" + subCode + ")";
                    }
                    mView.promptText(PayWayActivity.TOAST_INFO, txt);
                }
            }

        });
    }


    /**
     * 发起刷脸支付请求.
     *
     * @param ftoken 刷脸返回的token
     * @param amount 支付金额
     */
    private void pay(String ftoken, String amount,String ytAmount) throws Exception {

        //按照新规则格式化ftoken
        String sign = doTerminalSign(ftoken);
        if(sign.length() == 0 || sign.equals(ftoken)){
            mDialog = new AlertDialog.Builder(App.getActivityStack().get(App.getActivityStack().size() - 1))
                    .setTitle("错误").setMessage("请重试").setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }).setCancelable(false).create();
            mDialog.show();
            return;
        }
        String aliFtoken = "ALRL" + ftoken + "," + sign;
        //这里改成走家乐福的接口
        mView.showProgress();
        ServiceInterface.getInstance().payTrade(JLFConstant.PAY_FACE_SCAN, "", amount, "", "", "1", ytAmount, aliFtoken);
        /*AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                App.getAppId(),
                App.getAppKey(),
                "json",
                "utf-8",
                null,
                "RSA2");
        AlipayTradePayRequest alipayTradePayRequest = new AlipayTradePayRequest();
        TradepayParam tradepayParam = new TradepayParam();
        tradepayParam.setOut_trade_no(UUID.randomUUID().toString());

        //auth_code和scene填写需要注意
        tradepayParam.setAuth_code(ftoken);
        tradepayParam.setScene("security_code");
        tradepayParam.setSubject("smilepay");
        tradepayParam.setStore_id("smilepay test");
        tradepayParam.setTimeout_express("5m");
        tradepayParam.setTotal_amount(amount);
        alipayTradePayRequest.setBizContent(JSON.toJSONString(tradepayParam));
        alipayClient.execute(alipayTradePayRequest,
                new AlipayCallBack() {

                    @Override
                    public AlipayResponse onResponse(AlipayResponse response) {
                        LogUtil.d("xxxxxx AlipayResponse "+response);
                        if (response != null && SMILEPAY_CODE_SUCCESS.equals(response.getCode())) {
                            mView.promptText(PayWayActivity.TOAST_SUCCESS, SMILEPAY_TXT_SUCCESS);
                        } else {
                            if (response != null) {
                                String subCode = response.getSubCode();
                                if (SMILEPAY_SUBCODE_LIMIT.equalsIgnoreCase(subCode)) {
                                    mView.promptText(PayWayActivity.TOAST_INFO, SMILEPAY_TXT_LIMIT);
                                } else if (SMILEPAY_SUBCODE_BALANCE_NOT_ENOUGH.equalsIgnoreCase(subCode)) {
                                    mView.promptText(PayWayActivity.TOAST_INFO, SMILEPAY_TXT_EBALANCE_NOT_ENOUGH);
                                } else if (SMILEPAY_SUBCODE_BANKCARD_BALANCE_NOT_ENOUGH.equalsIgnoreCase(subCode)) {
                                    mView.promptText(PayWayActivity.TOAST_INFO, SMILEPAY_TXT_BANKCARD_BALANCE_NOT_ENOUGH);
                                } else {
                                    mView.promptText(PayWayActivity.TOAST_FAIL, SMILEPAY_TXT_FAIL);
                                }
                            } else {
                                mView.promptText(PayWayActivity.TOAST_FAIL, SMILEPAY_TXT_FAIL);
                            }
                        }
                        return null;
                    }
                });
        return;*/
    }


    protected String doTerminalSign(String barCode) {
        try {
            int result[] = new int[1];
            String signedHelloWorld = mXDeviceManager.sign(barCode.getBytes(), result);

            if (result[0] != 0) {
                ToastUtils.toastShow("机具管控参数错误:" + result[0], ToastUtils.ERROR);
                return "";
            } else {
                return signedHelloWorld;
            }
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.e("BASE ACTIVITY "+ e.getMessage());
            return barCode;
        }
    }
}
